package com.view.loadmore;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;

import com.utils.BuildConfig;
import com.utils.LogUtils;

/**
 * 加载更多RecyclerView
 */
public class LoadMoreRecyclerView extends RecyclerView {

    private static final String TAG = "LoadMoreRecyclerView";

    /**
     * 是否自动加载
     * true:自动加载
     * false:点击加载
     */
    private boolean autoLoad = true;
    /******静止状态*****/
    public static final int LOAD_IDLE = -1;
    /******正在加载展示*****/
    public static final int LOAD_LOADING_SHOW = 0;
    /********点击加载展示******/
    public static final int LOAD_CLICK_SHOW = 1;
    /*****加载完成，加载全部*****/
    public static final int LOAD_COMPLETE = 2;
    /*****加载失败*****/
    public static final int LOAD_FAIL = 3;

    private int loadMoreStatus = LOAD_IDLE;

    private OnLoadMoreListener onLoadmoreListener;

    private boolean isLoading = false;

    private boolean canLoad = true;

    //文字相关参数
    private String completeText = "已加载全部";//加载完成的文字
    private String clickLoadText = "点击加载下一页";//不自动加载时点击加载的文字
    private String failText = "数据加载失败";//加载失败的文字
    private String loadingText = "加载中...";//加载中的文字

    private boolean pendingLoad = false;
    private int scrollState = SCROLL_STATE_IDLE;

    private LoadMoreView loadMoreView;

    public LoadMoreView getLoadMoreView() {
        return loadMoreView;
    }

    public LoadMoreRecyclerView(@NonNull Context context) {
        this(context, null);
    }

    public LoadMoreRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);

        createLoadView();
        addOnScrollListener(new OnScrollListener() {
            @Override
            public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                scrollState = newState;
                if (onLoadmoreListener == null || !canLoad || isLoading || !pendingLoad) {
                    return;
                }
                if (newState == SCROLL_STATE_IDLE && checkCanLoaMore()) {
                    onLoading();
                }
            }
        });
    }

    /**
     * 检查是否达到加载更多的条件
     *
     * @return
     */
    private boolean checkCanLoaMore() {
        LayoutManager layoutManager = getLayoutManager();
        if (layoutManager == null) {
            return false;
        }
        int childCount = layoutManager.getChildCount();
        if (childCount == 0) {
            return false;
        }
        int itemCount = layoutManager.getItemCount();
        if (itemCount == 0) {
            return false;
        }
        if (getLastVisiblePos(layoutManager) == itemCount - 1) {
            return true;
        }
        return false;
    }

    private int getLastVisiblePos(LayoutManager layoutManager) {
        if (layoutManager instanceof LinearLayoutManager) {
            return ((LinearLayoutManager) layoutManager).findLastVisibleItemPosition();
        } else if (layoutManager instanceof StaggeredGridLayoutManager) {
            int[] ints = new int[2];
            ((StaggeredGridLayoutManager) layoutManager).findLastVisibleItemPositions(ints);
            return Math.max(ints[0], ints[1]);
        } else {
            if (BuildConfig.DEBUG) {
                throw new IllegalArgumentException("LayoutManager is not sport." + layoutManager.getClass().getName());
            } else {
                return 0;
            }
        }
    }


    private void createLoadView() {
        //每次创建一个，防止ViewHolder views must not be attached when created.
        loadMoreView = new LoadMoreView(getContext());
        loadMoreView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int loadMoreStatus = getLoadMoreStatus();
                if (loadMoreStatus == LoadMoreRecyclerView.LOAD_FAIL) {
                    onFailClick();
                }
                if (loadMoreStatus == LoadMoreRecyclerView.LOAD_CLICK_SHOW) {
                    onLoadClick();
                }
            }
        });
        loadMoreView.addOnAttachStateChangeListener(new OnAttachStateChangeListener() {
            @Override
            public void onViewAttachedToWindow(View v) {
                if (!canLoad) {
                    return;
                }
                if (loadMoreStatus == LOAD_IDLE) {
                    if (isAutoLoad() && !isLoading) {
                        onPendingLoading();
                    } else {
                        onClickLoadShow();
                    }
                }
            }

            @Override
            public void onViewDetachedFromWindow(View v) {
            }
        });
    }

    public boolean isLoading() {
        return isLoading;
    }

    public boolean isAutoLoad() {
        return autoLoad;
    }

    public void setAutoLoad(boolean autoLoad) {
        this.autoLoad = autoLoad;
    }

    public void setAdapter(@Nullable LoadMoreAdapter adapter) {
        super.setAdapter(adapter);
    }

    public void setOnLoadmoreListener(OnLoadMoreListener onLoadmoreListener) {
        this.onLoadmoreListener = onLoadmoreListener;
    }

    public boolean canLoad() {
        return canLoad;
    }

    public void setCanLoadMore(boolean canLoad) {
        this.canLoad = canLoad;
        if (canLoad) {
            onIdle();
        } else {
            onComplete();
        }
    }

    public void stopLoad() {
        LogUtils.d(TAG, "stopLoad: ");
        onIdle();
    }

    /**
     * 失败
     */
    public void onFail() {
        LogUtils.d(TAG, "onFail: ");
        loadMoreStatus = LOAD_FAIL;
        isLoading = false;
        if (getAdapter() != null && loadMoreView != null) {
            loadMoreView.fail(failText);
        }
    }

    public void onComplete() {
        LogUtils.d(TAG, "onComplete: ");
        loadMoreStatus = LOAD_COMPLETE;
        isLoading = false;
        if (getAdapter() != null && loadMoreView != null) {
            loadMoreView.complete(completeText);
        }
    }


    //初始状态
    private void onIdle() {
        LogUtils.d(TAG, "onIdle: ");
        loadMoreStatus = LOAD_IDLE;
        isLoading = false;
        if (getAdapter() != null && loadMoreView != null) {
            loadMoreView.non();
        }
    }

    private void onLoading() {
        LogUtils.d(TAG, "onLoading: " + pendingLoad);
        //显示加载中的动画
        loadMoreStatus = LOAD_LOADING_SHOW;
        isLoading = true;
        onLoadmoreListener.onLoadMore();
        pendingLoad = false;
    }

    /**
     * 待loading状态
     */
    private void onPendingLoading() {
        LogUtils.d(TAG, "onPendingLoading: " + getLoadMoreStatus());
        if (onLoadmoreListener == null) {
            return;
        }
        if (!canLoad) {
            return;
        }
        if (getAdapter() != null && loadMoreView != null) {
            loadMoreView.loading(loadingText);
        }
        //放到待load里,延时触发回调，待不滚动后触发加载，防止滚动中触发刷新导致崩溃
        if (scrollState == SCROLL_STATE_IDLE && checkCanLoaMore()) {
            onLoading();
        } else {
            pendingLoad = true;
        }
    }

    public void onFailClick() {
        LogUtils.d(TAG, "onFailClick: ");
        onPendingLoading();
    }

    /**
     * 点击加载
     */
    public void onLoadClick() {
        LogUtils.d(TAG, "onLoadClick: ");
        onPendingLoading();
    }

    public void onClickLoadShow() {
        LogUtils.d(TAG, "onClickLoadShow: ");
        loadMoreStatus = LOAD_CLICK_SHOW;
        if (getAdapter() != null && loadMoreView != null) {
            loadMoreView.clickLoad(clickLoadText);
        }
    }


    public interface OnLoadMoreListener {
        void onLoadMore();
    }

    public int getLoadMoreStatus() {
        return loadMoreStatus;
    }

    /********************文案设置***********************/
    public void setCompleteText(String completeText) {
        this.completeText = completeText;
    }

    public void setClickLoadText(String clickLoadText) {
        this.clickLoadText = clickLoadText;
    }

    public void setFailText(String failText) {
        this.failText = failText;
    }

    public void setLoadingText(String loadingText) {
        this.loadingText = loadingText;
    }
}
